﻿using System.Net;
using System;
using System.Collections.Generic;

namespace minimus
{
    public class BestDNSResolver
    {
        private class IPAddressEntry : IComparable<IPAddressEntry>
        {
            public IPEndPoint EP;
            public int Failures = 0;
            public IPAddressEntry(IPAddress ip, int port)
            {
                this.EP = new IPEndPoint(ip, port);
            }
            public int CompareTo(IPAddressEntry other)
            {
                return other.Failures.CompareTo(this.Failures);
            }

        }
        private List<IPAddressEntry> HostIPs = new List<IPAddressEntry>();
        private int m_Port;
        private string m_Hostname;
        public BestDNSResolver(string hostname, int port)
        {
            m_Port = port;
            m_Hostname = hostname;
            StartResolving();
        }

        private void StartResolving()
        {
            Dns.BeginGetHostAddresses(m_Hostname, new AsyncCallback(DnsCallback), null);
        }

        public string Host
        {
            get
            {
                return m_Hostname;
            }
            set
            {
                if (m_Hostname == value)
                    return;
                m_Hostname = value;
                StartResolving();
            }
        }
        public int Port
        {
            get
            {
                return m_Port;
            }
            set
            {
                if (m_Port == value)
                    return;
                m_Port = value;
                foreach (IPAddressEntry ip in HostIPs)
                    ip.EP.Port = m_Port;
            }
        }
        private void DnsCallback(IAsyncResult result)
        {
            try
            {
                IPAddress[] ips = Dns.EndGetHostAddresses(result);
                foreach (IPAddress ip in ips)
                    HostIPs.Add(new IPAddressEntry(ip, m_Port));
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }
        }
        public IPEndPoint GetBestIP()
        {
            if (HostIPs.Count <= 0)
                return null;
            return HostIPs[HostIPs.Count - 1].EP;
        }
        public void BestIPFailed()
        {
            if (HostIPs.Count <= 0)
                return;
            HostIPs[HostIPs.Count - 1].Failures++;
            HostIPs.Sort();
        }
    }
}